/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package DAO;

import DAO.exceptions.NonexistentEntityException;
import DAO.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import modelo.PersonaAtencion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import modelo.Area;
import modelo.Ticket;
import modelo.TipoServicio;

/**
 *
 * @author MANUEL
 */
public class AreaJpaController implements Serializable {

    public AreaJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Area area) throws PreexistingEntityException, Exception {
        if (area.getPersonaAtencionCollection() == null) {
            area.setPersonaAtencionCollection(new ArrayList<PersonaAtencion>());
        }
        if (area.getTicketCollection() == null) {
            area.setTicketCollection(new ArrayList<Ticket>());
        }
        if (area.getTipoServicioCollection() == null) {
            area.setTipoServicioCollection(new ArrayList<TipoServicio>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<PersonaAtencion> attachedPersonaAtencionCollection = new ArrayList<PersonaAtencion>();
            for (PersonaAtencion personaAtencionCollectionPersonaAtencionToAttach : area.getPersonaAtencionCollection()) {
                personaAtencionCollectionPersonaAtencionToAttach = em.getReference(personaAtencionCollectionPersonaAtencionToAttach.getClass(), personaAtencionCollectionPersonaAtencionToAttach.getNumAtencion());
                attachedPersonaAtencionCollection.add(personaAtencionCollectionPersonaAtencionToAttach);
            }
            area.setPersonaAtencionCollection(attachedPersonaAtencionCollection);
            Collection<Ticket> attachedTicketCollection = new ArrayList<Ticket>();
            for (Ticket ticketCollectionTicketToAttach : area.getTicketCollection()) {
                ticketCollectionTicketToAttach = em.getReference(ticketCollectionTicketToAttach.getClass(), ticketCollectionTicketToAttach.getNumTicket());
                attachedTicketCollection.add(ticketCollectionTicketToAttach);
            }
            area.setTicketCollection(attachedTicketCollection);
            Collection<TipoServicio> attachedTipoServicioCollection = new ArrayList<TipoServicio>();
            for (TipoServicio tipoServicioCollectionTipoServicioToAttach : area.getTipoServicioCollection()) {
                tipoServicioCollectionTipoServicioToAttach = em.getReference(tipoServicioCollectionTipoServicioToAttach.getClass(), tipoServicioCollectionTipoServicioToAttach.getNumTipo());
                attachedTipoServicioCollection.add(tipoServicioCollectionTipoServicioToAttach);
            }
            area.setTipoServicioCollection(attachedTipoServicioCollection);
            em.persist(area);
            for (PersonaAtencion personaAtencionCollectionPersonaAtencion : area.getPersonaAtencionCollection()) {
                Area oldAreaNumAreaOfPersonaAtencionCollectionPersonaAtencion = personaAtencionCollectionPersonaAtencion.getAreaNumArea();
                personaAtencionCollectionPersonaAtencion.setAreaNumArea(area);
                personaAtencionCollectionPersonaAtencion = em.merge(personaAtencionCollectionPersonaAtencion);
                if (oldAreaNumAreaOfPersonaAtencionCollectionPersonaAtencion != null) {
                    oldAreaNumAreaOfPersonaAtencionCollectionPersonaAtencion.getPersonaAtencionCollection().remove(personaAtencionCollectionPersonaAtencion);
                    oldAreaNumAreaOfPersonaAtencionCollectionPersonaAtencion = em.merge(oldAreaNumAreaOfPersonaAtencionCollectionPersonaAtencion);
                }
            }
            for (Ticket ticketCollectionTicket : area.getTicketCollection()) {
                Area oldNumAreaOfTicketCollectionTicket = ticketCollectionTicket.getNumArea();
                ticketCollectionTicket.setNumArea(area);
                ticketCollectionTicket = em.merge(ticketCollectionTicket);
                if (oldNumAreaOfTicketCollectionTicket != null) {
                    oldNumAreaOfTicketCollectionTicket.getTicketCollection().remove(ticketCollectionTicket);
                    oldNumAreaOfTicketCollectionTicket = em.merge(oldNumAreaOfTicketCollectionTicket);
                }
            }
            for (TipoServicio tipoServicioCollectionTipoServicio : area.getTipoServicioCollection()) {
                Area oldNumAreaOfTipoServicioCollectionTipoServicio = tipoServicioCollectionTipoServicio.getNumArea();
                tipoServicioCollectionTipoServicio.setNumArea(area);
                tipoServicioCollectionTipoServicio = em.merge(tipoServicioCollectionTipoServicio);
                if (oldNumAreaOfTipoServicioCollectionTipoServicio != null) {
                    oldNumAreaOfTipoServicioCollectionTipoServicio.getTipoServicioCollection().remove(tipoServicioCollectionTipoServicio);
                    oldNumAreaOfTipoServicioCollectionTipoServicio = em.merge(oldNumAreaOfTipoServicioCollectionTipoServicio);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findArea(area.getNumArea()) != null) {
                throw new PreexistingEntityException("Area " + area + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Area area) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Area persistentArea = em.find(Area.class, area.getNumArea());
            Collection<PersonaAtencion> personaAtencionCollectionOld = persistentArea.getPersonaAtencionCollection();
            Collection<PersonaAtencion> personaAtencionCollectionNew = area.getPersonaAtencionCollection();
            Collection<Ticket> ticketCollectionOld = persistentArea.getTicketCollection();
            Collection<Ticket> ticketCollectionNew = area.getTicketCollection();
            Collection<TipoServicio> tipoServicioCollectionOld = persistentArea.getTipoServicioCollection();
            Collection<TipoServicio> tipoServicioCollectionNew = area.getTipoServicioCollection();
            Collection<PersonaAtencion> attachedPersonaAtencionCollectionNew = new ArrayList<PersonaAtencion>();
            for (PersonaAtencion personaAtencionCollectionNewPersonaAtencionToAttach : personaAtencionCollectionNew) {
                personaAtencionCollectionNewPersonaAtencionToAttach = em.getReference(personaAtencionCollectionNewPersonaAtencionToAttach.getClass(), personaAtencionCollectionNewPersonaAtencionToAttach.getNumAtencion());
                attachedPersonaAtencionCollectionNew.add(personaAtencionCollectionNewPersonaAtencionToAttach);
            }
            personaAtencionCollectionNew = attachedPersonaAtencionCollectionNew;
            area.setPersonaAtencionCollection(personaAtencionCollectionNew);
            Collection<Ticket> attachedTicketCollectionNew = new ArrayList<Ticket>();
            for (Ticket ticketCollectionNewTicketToAttach : ticketCollectionNew) {
                ticketCollectionNewTicketToAttach = em.getReference(ticketCollectionNewTicketToAttach.getClass(), ticketCollectionNewTicketToAttach.getNumTicket());
                attachedTicketCollectionNew.add(ticketCollectionNewTicketToAttach);
            }
            ticketCollectionNew = attachedTicketCollectionNew;
            area.setTicketCollection(ticketCollectionNew);
            Collection<TipoServicio> attachedTipoServicioCollectionNew = new ArrayList<TipoServicio>();
            for (TipoServicio tipoServicioCollectionNewTipoServicioToAttach : tipoServicioCollectionNew) {
                tipoServicioCollectionNewTipoServicioToAttach = em.getReference(tipoServicioCollectionNewTipoServicioToAttach.getClass(), tipoServicioCollectionNewTipoServicioToAttach.getNumTipo());
                attachedTipoServicioCollectionNew.add(tipoServicioCollectionNewTipoServicioToAttach);
            }
            tipoServicioCollectionNew = attachedTipoServicioCollectionNew;
            area.setTipoServicioCollection(tipoServicioCollectionNew);
            area = em.merge(area);
            for (PersonaAtencion personaAtencionCollectionOldPersonaAtencion : personaAtencionCollectionOld) {
                if (!personaAtencionCollectionNew.contains(personaAtencionCollectionOldPersonaAtencion)) {
                    personaAtencionCollectionOldPersonaAtencion.setAreaNumArea(null);
                    personaAtencionCollectionOldPersonaAtencion = em.merge(personaAtencionCollectionOldPersonaAtencion);
                }
            }
            for (PersonaAtencion personaAtencionCollectionNewPersonaAtencion : personaAtencionCollectionNew) {
                if (!personaAtencionCollectionOld.contains(personaAtencionCollectionNewPersonaAtencion)) {
                    Area oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion = personaAtencionCollectionNewPersonaAtencion.getAreaNumArea();
                    personaAtencionCollectionNewPersonaAtencion.setAreaNumArea(area);
                    personaAtencionCollectionNewPersonaAtencion = em.merge(personaAtencionCollectionNewPersonaAtencion);
                    if (oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion != null && !oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion.equals(area)) {
                        oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion.getPersonaAtencionCollection().remove(personaAtencionCollectionNewPersonaAtencion);
                        oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion = em.merge(oldAreaNumAreaOfPersonaAtencionCollectionNewPersonaAtencion);
                    }
                }
            }
            for (Ticket ticketCollectionOldTicket : ticketCollectionOld) {
                if (!ticketCollectionNew.contains(ticketCollectionOldTicket)) {
                    ticketCollectionOldTicket.setNumArea(null);
                    ticketCollectionOldTicket = em.merge(ticketCollectionOldTicket);
                }
            }
            for (Ticket ticketCollectionNewTicket : ticketCollectionNew) {
                if (!ticketCollectionOld.contains(ticketCollectionNewTicket)) {
                    Area oldNumAreaOfTicketCollectionNewTicket = ticketCollectionNewTicket.getNumArea();
                    ticketCollectionNewTicket.setNumArea(area);
                    ticketCollectionNewTicket = em.merge(ticketCollectionNewTicket);
                    if (oldNumAreaOfTicketCollectionNewTicket != null && !oldNumAreaOfTicketCollectionNewTicket.equals(area)) {
                        oldNumAreaOfTicketCollectionNewTicket.getTicketCollection().remove(ticketCollectionNewTicket);
                        oldNumAreaOfTicketCollectionNewTicket = em.merge(oldNumAreaOfTicketCollectionNewTicket);
                    }
                }
            }
            for (TipoServicio tipoServicioCollectionOldTipoServicio : tipoServicioCollectionOld) {
                if (!tipoServicioCollectionNew.contains(tipoServicioCollectionOldTipoServicio)) {
                    tipoServicioCollectionOldTipoServicio.setNumArea(null);
                    tipoServicioCollectionOldTipoServicio = em.merge(tipoServicioCollectionOldTipoServicio);
                }
            }
            for (TipoServicio tipoServicioCollectionNewTipoServicio : tipoServicioCollectionNew) {
                if (!tipoServicioCollectionOld.contains(tipoServicioCollectionNewTipoServicio)) {
                    Area oldNumAreaOfTipoServicioCollectionNewTipoServicio = tipoServicioCollectionNewTipoServicio.getNumArea();
                    tipoServicioCollectionNewTipoServicio.setNumArea(area);
                    tipoServicioCollectionNewTipoServicio = em.merge(tipoServicioCollectionNewTipoServicio);
                    if (oldNumAreaOfTipoServicioCollectionNewTipoServicio != null && !oldNumAreaOfTipoServicioCollectionNewTipoServicio.equals(area)) {
                        oldNumAreaOfTipoServicioCollectionNewTipoServicio.getTipoServicioCollection().remove(tipoServicioCollectionNewTipoServicio);
                        oldNumAreaOfTipoServicioCollectionNewTipoServicio = em.merge(oldNumAreaOfTipoServicioCollectionNewTipoServicio);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = area.getNumArea();
                if (findArea(id) == null) {
                    throw new NonexistentEntityException("The area with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Area area;
            try {
                area = em.getReference(Area.class, id);
                area.getNumArea();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The area with id " + id + " no longer exists.", enfe);
            }
            Collection<PersonaAtencion> personaAtencionCollection = area.getPersonaAtencionCollection();
            for (PersonaAtencion personaAtencionCollectionPersonaAtencion : personaAtencionCollection) {
                personaAtencionCollectionPersonaAtencion.setAreaNumArea(null);
                personaAtencionCollectionPersonaAtencion = em.merge(personaAtencionCollectionPersonaAtencion);
            }
            Collection<Ticket> ticketCollection = area.getTicketCollection();
            for (Ticket ticketCollectionTicket : ticketCollection) {
                ticketCollectionTicket.setNumArea(null);
                ticketCollectionTicket = em.merge(ticketCollectionTicket);
            }
            Collection<TipoServicio> tipoServicioCollection = area.getTipoServicioCollection();
            for (TipoServicio tipoServicioCollectionTipoServicio : tipoServicioCollection) {
                tipoServicioCollectionTipoServicio.setNumArea(null);
                tipoServicioCollectionTipoServicio = em.merge(tipoServicioCollectionTipoServicio);
            }
            em.remove(area);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Area> findAreaEntities() {
        return findAreaEntities(true, -1, -1);
    }

    public List<Area> findAreaEntities(int maxResults, int firstResult) {
        return findAreaEntities(false, maxResults, firstResult);
    }

    private List<Area> findAreaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Area.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Area findArea(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Area.class, id);
        } finally {
            em.close();
        }
    }

    public int getAreaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Area> rt = cq.from(Area.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
